home *** CD-ROM | disk | FTP | other *** search
/ CD-ROM Data 1996 December / CD-ROM DATA 96.ISO / INTERNET / OFFLINE / SHAREWAR / WWWPOLL.TAR / wwwpoll.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-07-14  |  23.1 KB  |  782 lines

  1. /* ------------------------------------------------------------------------ */
  2.  
  3. /*  WWW Poll Script, Version 1.1
  4.     Copyright 1994, Creative Internet Designs
  5.     by Joseph E. Cates and Aure Prochazka
  6.  
  7.     Documentation and most current version available at:
  8.       http://www.galcit.caltech.edu/~ta/demos/wwwpoll/wwwpoll.html
  9.  
  10. */
  11.  
  12. #include "wwwpoll.h"
  13.  
  14.         /* structures for form results */
  15.  
  16.     typedef struct {
  17.       char *name;
  18.       char *val;
  19.     } formres_entry;
  20.  
  21.     typedef struct {
  22.       int nvotes;
  23.       char name[MAX_NAME_LEN];
  24.     } list_entry;
  25.  
  26.      typedef struct {
  27.       char name[MAX_VOTER_LEN];
  28.     } voterlog_entry;
  29.  
  30.  
  31.    void wr_list(char *listname);
  32.    void wr_htinc_file(char *listname);
  33.    void wr_log(char *s1, char *s2);
  34.    void load_list(char *listname);
  35.         
  36.    void disp_main_page(int istatus);
  37.    void add_entry_page(char *list);
  38.    void html_header(char *s1, char *s2);
  39.         
  40.    void already_got_one();
  41.    void too_many_items();
  42.    void bad_option_for_question();
  43.    void bad_form_res();
  44.  
  45.    void err_msg(char *s1, char *s2);
  46.    void error_footer(char *s);
  47.    void input_err(int err_code);
  48.  
  49.    int include_file(char *flname);
  50.  
  51.    void get_host_info(char *hostinfo, int maxlength);
  52.    void strip_end_cr(char *s);
  53.    void strip_white(char *s);
  54.  
  55.    void unescape_url(char *url);
  56.    void plus_to_space(char *s);
  57.  
  58.    char *makeword(char *line, char stop);
  59.    char *fmakeword(FILE *f, char stop, int *len);
  60.    char x2c(char *what);
  61.  
  62.    /* ----- global variables ----- */
  63.    int totalnumvotes = 0, numvoterlog;
  64.    int nquest, novoteflag = 0, nitems;
  65.        
  66.    char ha[MAX_VOTER_LEN], lastvoter[MAX_VOTER_LEN];
  67.  
  68.    char qheader[BUF_LEN], qtitle[BUF_LEN];
  69.    char vplus_gif[BUF_LEN], vminus_gif[BUF_LEN], add_gif[BUF_LEN];
  70.    char buf[BUF_LEN];
  71.  
  72.    formres_entry entries[MAX_FORM_RES];
  73.    list_entry blist[MAX_ITEMS];
  74.  
  75.    voterlog_entry *vlog_ptr0;
  76.  
  77.    /* flags in list file to customize handling of a question
  78.      iadd_flag    - can users add entries (0 = no, ELSE = yes)
  79.      ivplus_flag  - can users vote plus (0 = no, ELSE = yes)
  80.      ivminus_flag - can users vote minus (0 = no, ELSE = yes)
  81.      isort_flag   - sort list by vote count (0 = no, ELSE = yes)
  82.      idcnt_flag   - display vote count (0 = no, ELSE = yes)
  83.    */
  84.    int iadd_flag, ivplus_flag, ivminus_flag, isort_flag, idcnt_flag;
  85.  
  86. int main(int argc, char *argv[]) {
  87.  
  88.    int cl, i, j, k, x, m=0, ivote, itmp;
  89.    FILE *fp;
  90.  
  91.    char action[64], list[64], flname[256]; 
  92.    char *rh_name, *rh_user;
  93.  
  94.    voterlog_entry *vlog_ptr1, *vlog_ptr2;
  95.      
  96.    /* if no argument supplied, just set action to do display main page */
  97.    if (argc < 2) strcpy(action, "display");
  98.      else strcpy(action, argv[1]);
  99.  
  100.    get_host_info(ha, MAX_VOTER_LEN-1);
  101.  
  102. /* --------------------------- DISPLAY PAGE ------------------------------- */
  103.    if (strcmp(action, "display") == 0) {
  104.  
  105.      wr_log(action, "");
  106.  
  107.      /* display the main HTML page and exit without rewriting files */
  108.      disp_main_page(0); exit(0);
  109.  
  110.  
  111. /* ------------------------------- INIT ----------------------------------- */
  112.    } else if (strcmp(action, "init") == 0) {
  113.  
  114.      wr_log(action, "");
  115.  
  116.     if ((fp = fopen(CFG_FILE, "r")) == NULL)
  117.       err_msg("Error opening configuration file for reading: ", CFG_FILE);
  118.  
  119.     fscanf(fp, "%d\n", &nquest);
  120.     if (nquest < 1) err_msg("Invalid number of polls in config file.", "");
  121.  
  122.     for (i = 0; i < nquest; i++) {
  123.  
  124.       fgets(list, BUF_LEN, fp); strip_end_cr(list);
  125.       if (ferror(fp)) err_msg("Error reading config file: ", CFG_FILE);
  126.  
  127.       /* load the list info */
  128.       load_list(list);
  129.             
  130.       /* write the HTML include file */
  131.       wr_htinc_file(list);
  132.  
  133.     }
  134.  
  135.     fclose(fp);
  136.  
  137.     /* display page and exit, don't need to rewrite the list files */
  138.     disp_main_page(0); exit(0);
  139.  
  140. /* ------------------------- ADD ENTRY OR VOTE ---------------------------- */
  141.    } else if ((strcmp(action, "vplus") == 0)  || (strcmp(action, "vminus") == 0)
  142.      || (strcmp(action, "procnew") == 0) || (strcmp(action, "add") == 0)) {
  143.  
  144.      /* requires 3 arguments, otherwise display page with error msg */
  145.      if (argc != 4) { disp_main_page(1); exit(0); }
  146.  
  147.      /* now get the list name (doubles as file name) */
  148.      strcpy(list, argv[2]);
  149.  
  150.      /* load the list info */
  151.      load_list(list);
  152.  
  153.      /* ---- voting, increment or decrement the item's number votes ---- */
  154.      if ((strcmp(action,"vplus") == 0) || (strcmp(action,"vminus") == 0)) {
  155.  
  156.        /* check for people guessing options that aren't allowed */
  157.        if ((strcmp(action,"vplus") == 0) && (ivplus_flag == 0))
  158.          bad_option_for_question();
  159.        if ((strcmp(action,"vminus") == 0) && (ivminus_flag == 0))
  160.          bad_option_for_question();
  161.  
  162.        ivote = atoi(argv[3]);                  /* which item */
  163.  
  164.        /* bad item number is probably a URL from an old poll */
  165.        if ((ivote < 0) || (ivote > nitems-1)) { disp_main_page(1); exit(0); }
  166.  
  167.        /* see if the current person is on the list of last voters */
  168.        for (vlog_ptr1=vlog_ptr0, i=0; i < numvoterlog; i++) {
  169.          if (strcmp(ha, (char *) vlog_ptr1) == 0) novoteflag = 1;
  170.          vlog_ptr1++;
  171.        }       
  172.  
  173.        if (novoteflag == 0) {
  174.  
  175.          wr_log(action, blist[ivote].name);
  176.  
  177.          /* shift list down and add latest to the end of the list */
  178.          vlog_ptr1 = vlog_ptr2 = vlog_ptr0; 
  179.          vlog_ptr2++;
  180.          for (i=0; i < numvoterlog-1; i++) {
  181.            strcpy((char *) vlog_ptr1, (char *) vlog_ptr2); 
  182.            vlog_ptr1++; vlog_ptr2++;
  183.          }
  184.          strcpy((char *) vlog_ptr1, ha);
  185.  
  186.          /* save in the last voter string variable for below */
  187.          strcpy(lastvoter, ha);
  188.   
  189.          totalnumvotes++;
  190.  
  191.          /* increment or decrement the items vote count */
  192.          if (strcmp(action, "vplus") == 0) ++blist[ivote].nvotes;
  193.            else --blist[ivote].nvotes;
  194.  
  195.        } else wr_log(action, "Error: Already Voted!");
  196.  
  197.      /* ---- display form for adding an entry ---- */
  198.      } else if (strcmp(action, "add") == 0) {
  199.  
  200.        wr_log(action, list);
  201.  
  202.        /* check for people guessing options that aren't allowed */
  203.        if (iadd_flag == 0) bad_option_for_question();
  204.  
  205.        /* if there are already too many items, don't let them add */
  206.        if (nitems >= MAX_ITEMS) too_many_items("");
  207.       
  208.        /* build html form to input the new entry */
  209.        add_entry_page(list); 
  210.  
  211.        /* exit now, we don't need to rewrite any of the files */ 
  212.        exit(0);
  213.  
  214.      /* ---- add the entry they typed in to the appropriate list ---- */
  215.      } else if (strcmp(action, "procnew") == 0) {
  216.  
  217.        /* check for people guessing options that aren't allowed */
  218.        if (iadd_flag == 0) bad_option_for_question();
  219.  
  220.        m = -1;
  221.  
  222.        if (getenv("CONTENT_LENGTH") == NULL) {
  223.          disp_main_page(1);
  224.          exit(0);
  225.        } else {
  226.          cl = atoi(getenv("CONTENT_LENGTH"));
  227.          for (x=0; cl && (!feof(stdin));x++) {
  228.            m=x;
  229.            entries[x].val = fmakeword(stdin,'&',&cl);
  230.            plus_to_space(entries[x].val);
  231.            unescape_url(entries[x].val);
  232.            entries[x].name = makeword(entries[x].val,'=');
  233.            strip_white(entries[0].name);
  234.            strip_white(entries[0].val);
  235.          }
  236.        }
  237.  
  238.        /* no forms probably means reloading after add, display page */
  239.        if (m == -1) { disp_main_page(1); exit(0); }
  240.  
  241.        /* did browser return one entry with correct name */
  242.        if ((m != 0) || (strcmp(entries[0].name, "item") != 0))
  243.           bad_form_res();
  244.  
  245.        wr_log(list, entries[0].val);
  246.  
  247.        if (strpbrk(entries[0].val, "<>&")) input_err(1);
  248.        if (strpbrk(entries[0].val, "\b\f\n\r\v")) input_err(2);
  249.        if (strpbrk(entries[0].val, "\"")) input_err(3);
  250.        if (strlen(entries[0].val) == 0) input_err(4);
  251.  
  252.        for (i = 0; i < nitems; i++) {
  253.          if (strcmp(entries[0].val, blist[i].name) == 0) already_got_one();
  254.        }
  255.  
  256.        /* increment the number of items count */
  257.        nitems++;
  258.  
  259.        /* put value and initialize to zero vote count */
  260.        strcpy(blist[nitems-1].name, entries[0].val);
  261.        blist[nitems-1].nvotes = 0;
  262.         
  263.      }
  264.  
  265. /* ------------------------- ELSE UNRECOGNIZED ---------------------------- */
  266.    } else {
  267.  
  268.      /* for bad argument, display the main HTML page and exit */
  269.      disp_main_page(-1); exit(0);
  270.  
  271.    }
  272.  
  273.  
  274.    if (isort_flag) {
  275.  
  276.      /* sort the items in order of the number of votes */
  277.      for (i = 0; i < nitems; i++) {
  278.        for (j = i; j < nitems; j++) {
  279.  
  280.          if (blist[j].nvotes > blist[i].nvotes) {
  281.  
  282.            itmp = blist[i].nvotes;
  283.            blist[i].nvotes = blist[j].nvotes;
  284.            blist[j].nvotes = itmp;
  285.  
  286.            strcpy(buf, blist[i].name);
  287.            strcpy(blist[i].name, blist[j].name);
  288.            strcpy(blist[j].name, buf);
  289.  
  290.          }
  291.        }
  292.      }
  293.  
  294.    }
  295.  
  296.    /* write the existing list back to the the list file */
  297.    wr_list(list);
  298.  
  299.    /* write the HTML include file */
  300.    wr_htinc_file(list);
  301.  
  302.    /* redisplay the page */
  303.    disp_main_page(0);
  304.  
  305.    exit(0);
  306.  
  307. }
  308.  
  309. /* ---------------------------------------------------------------------------
  310.    disp_main_page: display the main poll page
  311.    ------------------------------------------------------------------------ */
  312.    void disp_main_page(int istatus) {
  313.  
  314.     int i, nquest;
  315.     FILE *fp;
  316.     char incflname[256];
  317.  
  318.     html_header("", "");
  319.  
  320.     if (istatus != 0) {
  321.  
  322.       printf(ERROR_IMG " The requested poll URL is incorrect, the URL is\n"
  323.         "probably from an old question. The correct URL to access the\n"
  324.         "poll is " POLL_HREF SERVER POLL_URL "</A>\n<HR>\n");
  325.  
  326.     } else if (novoteflag != 0) {
  327.  
  328.       printf(ERROR_IMG " Voter from <B>%s</B>.  Your host is in the\n"
  329.         "list of recent voters, so you can't vote again.  Try another\n"
  330.         "question!\n<HR>\n", ha);
  331.  
  332.     } else {
  333.  
  334.       #ifdef HTML_LEADIN
  335.         printf(HTML_LEADIN);
  336.       #endif
  337.  
  338.     }
  339.  
  340.     if ((fp = fopen(CFG_FILE, "r")) == NULL)
  341.       err_msg("Error opening configuration file for reading: ", CFG_FILE);
  342.  
  343.     fscanf(fp, "%d\n", &nquest);
  344.     if (nquest < 1) err_msg("Invalid number of polls in config file.", "");
  345.  
  346.     for (i = 0; i < nquest; i++) {
  347.  
  348.       fgets(buf, BUF_LEN, fp); strip_end_cr(buf);
  349.       if (ferror(fp)) err_msg("Error reading config file.", CFG_FILE);
  350.  
  351.       /* this only works with NCSA 1.1, replaced for other versions */
  352.       /* printf("<INC SRV \"" INC_URL_BASE "%s.htinc\">\n", buf); */
  353.  
  354.       /* build the filename */
  355.       sprintf(incflname, HTINC_FILE_DIR "%s.htinc", buf);
  356.  
  357.       /* include the file directly from the code */
  358.       if (include_file(incflname) != 0)
  359.         err_msg("Error including htinc file:", incflname);
  360.  
  361.       printf("<HR>\n");
  362.  
  363.     }
  364.  
  365.     fclose(fp);
  366.  
  367.     #ifdef HTML_FOOTER
  368.       printf(HTML_FOOTER);
  369.     #endif
  370.  
  371.     printf("</BODY>\n</HTML>\n");
  372.  
  373.    }
  374.  
  375. /* ---------------------------------------------------------------------------
  376.    wr_htinc_file: write htinc (HTML include file) data to file
  377.    ------------------------------------------------------------------------ */
  378.    void wr_htinc_file(char *listname) {
  379.  
  380.      int i;
  381.      char flname[256];
  382.      FILE *fp;
  383.  
  384.      if ((nitems < MIN_ITEMS) || (nitems > MAX_ITEMS))
  385.        err_msg("Invalid number of items trying to write include file.", "");
  386.  
  387.      /* build the filename */
  388.      sprintf(flname, HTINC_FILE_DIR "%s.htinc", listname);
  389.  
  390.      if ((fp = fopen(flname, "w")) == NULL)
  391.        err_msg("Error opening include file for writing.", flname);
  392.  
  393.      fprintf(fp, "%s\n%s\n", qheader, qtitle);
  394.  
  395.      fprintf(fp, "<DL>\n<DD>\n");
  396.  
  397.      for (i = 0; i < nitems; i++) {
  398.  
  399.        if (ivplus_flag) {
  400.          fprintf(fp, "<A HREF=\"" POLL_URL "?vplus+%s+%d\">" VPLUS_IMG "</A>",
  401.            listname, i, vplus_gif);
  402.        }
  403.      
  404.        fprintf(fp, " ");
  405.     
  406.        if (ivminus_flag) {
  407.          fprintf(fp, "<A HREF=\"" POLL_URL "?vminus+%s+%d\">" VMINUS_IMG "</A>",
  408.            listname, i, vminus_gif);
  409.        }
  410.      
  411.        if (idcnt_flag) {
  412.          fprintf(fp, " %s (%d)<P>\n", blist[i].name, blist[i].nvotes);
  413.        } else {
  414.          fprintf(fp, " %s<P>\n", blist[i].name);
  415.        }
  416.  
  417.        if (ferror(fp)) err_msg("Error writing to include file:", flname);
  418.  
  419.      }
  420.  
  421.      /* only display add button if user's can add to the list */
  422.      if (iadd_flag) {
  423.        fprintf(fp, "<A HREF=\"" POLL_URL "?add+%s+0\">" ADD_IMG "</A>\n",
  424.          listname, add_gif);
  425.      }
  426.     
  427.      fprintf(fp, "</DD>\n");
  428.      fprintf(fp, "<P>\n<DT>Total votes: %d, Last vote from: %s</DT>\n", 
  429.        totalnumvotes, lastvoter);
  430.      fprintf(fp, "</DL>\n");
  431.  
  432.      fclose(fp);
  433.  
  434.    }
  435.  
  436. /* ---------------------------------------------------------------------------
  437.    add_entry_page: display the form to add an entry
  438.    ------------------------------------------------------------------------ */
  439.    void add_entry_page(char *list) {
  440.  
  441.      int i;
  442.  
  443.      html_header(": Add Entry", "");
  444.  
  445.      printf("The current entries for this question are:\n<P>\n");
  446.      printf("%s\n<UL>\n", qtitle);
  447.  
  448.      for (i = 0; i < nitems; i++) {
  449.        printf("<LI>%s (%d)\n</LI>", blist[i].name, blist[i].nvotes);
  450.      }
  451.     
  452.      printf("</UL>\n<HR>\n");
  453.  
  454.      printf("<FORM METHOD=\"POST\" ACTION=\"" POLL_URL "?procnew+%s+0\">\n",
  455.        list);
  456.     
  457.      printf("<B>Enter Item Name:</B><BR>\n"
  458.        "<INPUT TYPE=\"text\" NAME=\"item\" SIZE=52 MAXLENGTH=%d>\n<P>\n",
  459.        MAX_NAME_LEN-2);
  460.  
  461.      printf("<P>\n<INPUT TYPE=\"submit\" VALUE=\" SUBMIT THE NEW ITEM \">\n"
  462.        "</FORM>\n");
  463.  
  464.      printf("<HR>\n<B>\n" POLL_HREF BACK_IMG "</A>\n"
  465.        "Quit Back to " POLL_HREF TITLE "</A>\n</B>\n");
  466.     
  467.      }
  468.  
  469. /* ---------------------------------------------------------------------------
  470.    html_header: header for html pages
  471.    ------------------------------------------------------------------------ */
  472.    void html_header(char *s1, char *s2) {
  473.  
  474.      printf("Content-type: text/html\n\n");
  475.  
  476.      printf("<HTML>\n<HEAD>\n");
  477.      printf("<TITLE>" TITLE "%s %s</TITLE>\n", s1, s2);
  478.      printf("</HEAD>\n<BODY>\n");
  479.      printf("<H2>" TITLE "%s %s</H2>\n<HR>", s1, s2);
  480.  
  481.    }
  482.  
  483. /* ---------------------------------------------------------------------------
  484.    load_list: load list data from file
  485.    ------------------------------------------------------------------------ */
  486.    void load_list(char *listname) {
  487.  
  488.      int i;
  489.      char flname[128];
  490.      FILE *fp;
  491.      voterlog_entry *vlog_ptr;
  492.  
  493.      /* build the filename */
  494.      sprintf(flname, LIST_FILE_DIR "%s.list", listname);
  495.  
  496.      /* open file for reading */
  497.      fp = fopen(flname, "r");
  498.  
  499.      /* file not found probably means an old poll URL, so just display */
  500.      if (fp == NULL) { disp_main_page(1); exit(0); }
  501.  
  502.      fgets(qheader, BUF_LEN, fp); strip_end_cr(qheader);
  503.      if (ferror(fp)) err_msg("Error reading list input file: ", flname);
  504.  
  505.      fgets(qtitle, BUF_LEN, fp); strip_end_cr(qtitle);
  506.      if (ferror(fp)) err_msg("Error reading list input file: ", flname);
  507.  
  508.      fscanf(fp, "%d\n%d\n%d\n%d\n%d\n", &iadd_flag, &ivplus_flag, 
  509.        &ivminus_flag, &isort_flag, &idcnt_flag);
  510.  
  511.      fgets(vplus_gif, BUF_LEN, fp); strip_end_cr(vplus_gif);
  512.      fgets(vminus_gif, BUF_LEN, fp); strip_end_cr(vminus_gif);
  513.      fgets(add_gif, BUF_LEN, fp); strip_end_cr(add_gif);
  514.  
  515.      fscanf(fp, "%d\n", &nitems);
  516.      if ((nitems < MIN_ITEMS) || (nitems > MAX_ITEMS))
  517.        err_msg("Invalid number of items in list input file: ", flname);
  518.     
  519.      if (ferror(fp)) err_msg("Error reading info from list file: ", flname);
  520.      if (feof(fp)) err_msg("End of file reading info from list file: ", flname);
  521.  
  522.      for (i = 0; i < nitems; i++) {
  523.  
  524.        fscanf(fp, "%d\n", &blist[i].nvotes);
  525.       
  526.        fgets(blist[i].name, MAX_NAME_LEN, fp);
  527.        strip_end_cr(blist[i].name);
  528.  
  529.        if (ferror(fp)) err_msg("Error reading items from list file: ", flname);
  530.        if (feof(fp)) err_msg("End of file reading items from list file: ", flname);
  531.  
  532.      }
  533.  
  534.      fscanf(fp, "%d\n", &totalnumvotes);
  535.  
  536.      /* number of voters to log */
  537.      fscanf(fp, "%d\n", &numvoterlog);
  538.  
  539.      if (numvoterlog > 0) { 
  540.      
  541.        /* allocate memory for the list of voters */
  542.        if ((vlog_ptr0 = malloc(numvoterlog * MAX_VOTER_LEN)) == NULL)
  543.          err_msg("Error attempting to allocate memory for voter log.", "");
  544.  
  545.        for (vlog_ptr=vlog_ptr0, i=0; i < numvoterlog; i++) {
  546.  
  547.          /* get the last persons to vote */
  548.          fgets((char *) vlog_ptr, BUF_LEN, fp); strip_end_cr((char *) vlog_ptr);
  549.  
  550.          /* save last voter in a normal string variable */
  551.          strcpy(lastvoter, (char *) vlog_ptr);
  552.  
  553.         /* increment to the next voter slot */
  554.          vlog_ptr++;
  555.       
  556.          if (ferror(fp)) err_msg("Error reading voters from list file: ", flname);
  557.          if (feof(fp)) err_msg("End of file reading voters from list file: ", flname);
  558.  
  559.        }
  560.      }    
  561.       
  562.      fclose(fp);
  563.  
  564.    }
  565.  
  566. /* ---------------------------------------------------------------------------
  567.    wr_list: write list data to file
  568.    ------------------------------------------------------------------------ */
  569.    void wr_list(char *listname) {
  570.  
  571.      char flname[128];
  572.      FILE *fp;
  573.      int i;
  574.      voterlog_entry *vlog_ptr;
  575.  
  576.      if ((nitems < MIN_ITEMS) || (nitems > MAX_ITEMS))
  577.        err_msg("Invalid number of items trying to write list file.", "");
  578.  
  579.      /* build the filename */
  580.      sprintf(flname, LIST_FILE_DIR "%s.list", listname);
  581.  
  582.      if ((fp = fopen(flname, "w")) == NULL)
  583.        err_msg("Error opening list file for writing:", flname);
  584.  
  585.      fprintf(fp, "%s\n%s\n", qheader, qtitle);
  586.      fprintf(fp, "%d\n%d\n%d\n%d\n%d\n", iadd_flag, ivplus_flag,
  587.        ivminus_flag, isort_flag, idcnt_flag);
  588.  
  589.      fprintf(fp, "%s\n%s\n%s\n", vplus_gif, vminus_gif, add_gif);
  590.  
  591.      fprintf(fp, "%d\n", nitems);
  592.      for (i = 0; i < nitems; i++) {
  593.        fprintf(fp, "%d\n%s\n", blist[i].nvotes, blist[i].name);
  594.        if (ferror(fp)) err_msg("Error writing items to list file: ", flname);
  595.      }
  596.     
  597.      fprintf(fp, "%d\n", totalnumvotes);
  598.     
  599.      fprintf(fp, "%d\n", numvoterlog);
  600.      for (vlog_ptr=vlog_ptr0, i=0; i < numvoterlog; i++) {
  601.        fprintf(fp, "%s\n", (char *) vlog_ptr);
  602.        vlog_ptr++;
  603.      }
  604.  
  605.      fprintf(fp, "\n");
  606.  
  607.      fclose(fp);
  608.  
  609.    }
  610.  
  611. /* ----------------------------------------------------------------------
  612.    wr_log: write info to the log file
  613.    ------------------------------------------------------------------- */
  614.    void wr_log(char *s1, char *s2) {
  615.  
  616.      char dstr[128];
  617.      FILE *fp_log;
  618.      struct tm *ptr;
  619.      time_t lt;
  620.  
  621.      /* ...generate date to put in the error log... */
  622.      lt = time(NULL);
  623.      ptr = localtime(<);
  624.      strftime(dstr, 40, "%B %d, %Y at %H:%M:%S", ptr);
  625.  
  626.      fp_log = fopen(LOG_FILE, "a");
  627.  
  628.      if (fp_log != NULL) {
  629.        fprintf(fp_log, "%s, %s, %s %s\n", ha, dstr, s1, s2);
  630.      }
  631.  
  632.      fclose(fp_log);
  633.  
  634.    }
  635.  
  636. /* ---------------------------------------------------------------------------
  637.    bad_form_res: bad form results returned by their browser
  638.    ------------------------------------------------------------------------ */
  639.    void bad_form_res() {
  640.  
  641.      html_header(": Form Input Error", "");
  642.     
  643.      printf("The form results were returned incorrectly by your browser.\n"
  644.        "Your browser may not correctly support the form elements (TEXT and\n"
  645.        "RADIO) used in this application\n<P>\n");
  646.  
  647.      printf("If you would like to report the problem, send e-mail to the\n"
  648.        "maintainers of the " TITLE " at <I>" E_MAIL "</I>.\n");
  649.  
  650.      error_footer(""); exit(0);
  651.  
  652.    }
  653.  
  654. /* ---------------------------------------------------------------------------
  655.    err_msg: error messages page for errors NOT caused by user input
  656.    ------------------------------------------------------------------------ */
  657.    void err_msg(char *s1, char *s2) {
  658.  
  659.      html_header(": Fatal Script Error", "");
  660.  
  661.      printf("An error occurred in the " TITLE " script. Please report\n"
  662.        "this problem to the maintainers of the " TITLE " at <I>"
  663.        E_MAIL "</I>. Thank you.\n<P>\n");
  664.  
  665.      printf("Error Message: <TT><B>%s%s</B></TT>\n<P>\n", s1, s2);
  666.  
  667.      printf("Any data entered may still be available from your viewer\n"
  668.        "by using BACK to return to the previous form.\n");
  669.  
  670.      error_footer(""); exit(1);
  671.  
  672.    }
  673.  
  674. /* ---------------------------------------------------------------------------
  675.    input_err: error messages caused by user input
  676.    ------------------------------------------------------------------------ */
  677.    void input_err(int err_code) {
  678.  
  679.      html_header(": Input Error", "");
  680.  
  681.      printf(ERROR_IMG " ");
  682.  
  683.      if (err_code == 1) {
  684.  
  685.        printf("Text input fields are not allowed to contain HTML tags or\n"
  686.          "the <code><</code>, <code>></code>, or <code>&</code>\n"
  687.          "characters.\n");
  688.  
  689.      } else if (err_code == 2) {
  690.  
  691.        printf("Text input fields are not allowed to contain carriage\n"
  692.          "returns, new line, backspace, form feed, or vertical tab codes.\n"
  693.          "(In fact, we don't know how you managed to get one in there\n"
  694.          "anyway.)\n");
  695.  
  696.      } else if (err_code == 3) {
  697.  
  698.        printf("At present, text input fields are not allowed to contain\n"
  699.          "double quotes (\").  This is because no uniform method exists\n"
  700.          "of marking the double quotes in forms that works with all\n"
  701.          "viewers.  Single quotes may, however, be freely used.\n");
  702.  
  703.      } else if (err_code == 4) {
  704.  
  705.        printf("Null input fields found.  To add an item to the " TITLE ",\n"
  706.          "all fields must contain an entry after leading and trailing\n"
  707.          "spaces are removed.\n");
  708.  
  709.      } else {
  710.  
  711.        printf("Unidentified text input error.\n");
  712.     
  713.      }
  714.  
  715.      printf("Please correct and resubmit the text.\n<P>\n");
  716.  
  717.      printf("The data entered may still be available from your viewer\n"
  718.        "by using BACK to return to the previous form.\n"); 
  719.  
  720.      error_footer(""); exit(0);
  721.  
  722.    }
  723.  
  724.  
  725. /* ----------------------------------------------------------------------
  726.    already_got_one: aleady have the same URL in the list
  727.    ------------------------------------------------------------------- */
  728.    void already_got_one() {
  729.  
  730.      html_header(": Already Got One", "");
  731.  
  732.      printf(ERROR_IMG " Sorry, the specified item is already in the\n"
  733.        "list. Please choose another item to add.\n");
  734.  
  735.      error_footer(""); exit(0);
  736.  
  737.    }
  738.  
  739. /* ----------------------------------------------------------------------
  740.    bad_option_for_question: bad option (vplus, vminus, add) for question
  741.    ------------------------------------------------------------------- */
  742.    void bad_option_for_question() {
  743.  
  744.      html_header(": Bad Option for Question", "");
  745.  
  746.      printf(ERROR_IMG " The option chosen is not available on the\n"
  747.        "current question.  In fact, we don't know how you got this\n"
  748.        "error message to appear? (Are you trying to guess a new\n"
  749.        "URL?)\n");
  750.  
  751.      error_footer(""); exit(0);
  752.  
  753.    }
  754.  
  755. /* ----------------------------------------------------------------------
  756.    too_many_items: too many items in list
  757.    ------------------------------------------------------------------- */
  758.    void too_many_items() {
  759.  
  760.      html_header(": Too Many Items", "");
  761.  
  762.      printf(ERROR_IMG " The maximum number of items allowed (%d) has\n"
  763.        "been reached.  Sorry, no new items can be added.\n", MAX_ITEMS);
  764.  
  765.      error_footer(""); exit(0);
  766.  
  767.    }
  768.  
  769. /* ----------------------------------------------------------------------
  770.    error_footer: footer for all error screens
  771.    ------------------------------------------------------------------- */
  772.    void error_footer(char *s) {
  773.  
  774.      printf("<HR>\n<B>\n" POLL_HREF BACK_IMG "</A>\n"
  775.        "Quit Back to " POLL_HREF TITLE "</A>\n</B>\n");
  776.     
  777.    }
  778.  
  779. /* end */
  780.  
  781.  
  782.